﻿using Yxinmt.Components;
using Yxinmt.Interface;
using Yxinmt.Utility;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Threading;

namespace Yxinmt.Windows
{
    public abstract class BaseWindow : IWindow
    {
        public Guid Id { get; set; }
        public string Name { get; set; }
        public List<IComponent> ComponentList { get; set; }
        public List<IControl> ControlList { get; set; }
        public System.Drawing.Point StartPoint { get; set; }
        public int TabIndex { get; set; }
        public System.Windows.Controls.Grid Grid { get; set; }
        public IWindow ParentWindow { get; set; }
        public System.Windows.Window Window { get; set; }
        public Dictionary<Guid, IDataGridViewControls> DataGridViewControlsDictionary { get; set; }
        public bool IsReceiver { get; set; }
        public List<IControl> ScrollViewerList { get; set; }

        protected List<IComponent> _ComponentList { get; set; }
        protected Dictionary<string, object> _View { get; set; }

        protected List<System.Windows.FrameworkElement> _WindowControlList { get; set; }
        protected System.Windows.Controls.Grid _PagePanel { get; set; }
        protected bool _IsDialog { get; set; }
        protected int _Opacity { get; set; }
        protected int _GridRowCount { get; set; }
        protected int _GridColumnCount { get; set; }

        protected void InitSet(string name= null)
        {
            Id = Guid.NewGuid();
            Name = string.IsNullOrEmpty(name) ? this.GetType().Name : name;

            _View = ViewConfig.GetView(Name);

            DataGridViewControlsDictionary = new Dictionary<Guid, IDataGridViewControls>();

            StartPoint = new System.Drawing.Point(30, 20);
            ComponentList = new List<IComponent>();
            ControlList = new List<IControl>();
            ScrollViewerList = new List<IControl>();
            PopupList = new List<IControl>();
            Title = _View.GetStringValue("Title");

            _Opacity = _View.GetValue<int>("Opacity");
            _IsDialogBack = true;

            double screenWidth = SystemParameters.PrimaryScreenWidth;
            double screenHeight = SystemParameters.PrimaryScreenHeight;

            this.Width = 1920;
            this.Height = screenHeight * 1920 / screenWidth;

            if (!this.Window.IsActive && !this.IsDialogWindow) this.Window.Activate();

            if (ParentWindow != null) TabIndex = ParentWindow.TabIndex;

            InitEventAction();
        }

        public IEventAction EventAction { get; set; }

        protected void SetTheme(string theme)
        {
            if (!_View.GetValue<bool>("IsTheme")) return;

            var properties = _View.GetValue<List<Dictionary<string, object>>>("properties");
            if (properties!= null)
            {
                var properies2 = new List<Dictionary<string, object>>();
                bool isTheme = false;
                Dictionary<string, object> themeView = null;
                foreach (var p in properties)
                {
                    if (p.GetStringValue("type") == "ThemeView")
                    {
                        isTheme = true;
                        if (p.GetStringValue("name") == theme) themeView = p;
                    }
                    else properies2.Add(p);
                }
                if (isTheme)
                {
                    _View["properties"] = properies2;
                    if (themeView != null)
                    {
                        var themeProperties = themeView.GetValue<List<Dictionary<string, object>>>("properties");
                        if (themeProperties != null)
                        {
                            foreach (var p in themeProperties)
                            {
                                setThemeProperty(p, _View, "");
                            }
                        }
                    }
                }
            }
        }

        void setThemeProperty(Dictionary<string, object> p, Dictionary<string,object> property, string parentName)
        {
            string name = property.GetStringValue("name");
            name = !string.IsNullOrEmpty(parentName) ? $"{parentName}/{name}" : name;

            var ns = p.GetStringValue("name").Split('.').ToList() ;
            if ((name + ".").Contains(ns[0] + '.'))
            {
                var obj = property;
                if (ns.Count == 1)
                {
                    foreach (var kvp in p) {
                        obj[kvp.Key] = kvp.Value;
                    }
                }
                else
                {
                    for (int i = 1; i < ns.Count; i++)
                    {
                        var n = ns[i];
                        if (i == ns.Count - 1)
                        {
                            setPropertyValue(obj, p, n);
                        }
                        else
                        {
                            if (obj[n] == null) break;
                            obj = obj[n] as Dictionary<string, object>;
                        }
                    }
                }
                return;
            }

            if (property.ContainsKey("properties"))
            {
                property.GetValue<List<Dictionary<string,object>>>("properties").ForEach(p2 => {
                    setThemeProperty(p,p2, name);
                });
            }
        }

        void setPropertyValue(Dictionary<string, object> obj, Dictionary<string, object> p, string n)
        {
            var inputType = p.GetStringValue("inputType");
            var valueName = inputType + "Value";
            if (p.ContainsKey(valueName)) obj[n] = p[valueName];
        }

        void InitEventAction()
        {
            EventAction = new EventAction();
            EventAction.PageAction = new PageAction();
        }

        public string Title { get; set; }

        public double Width { get; set; }
        public double Height { get; set; }

        protected void SetWindow()
        {
            Grid = this.GetGrid(_View);
            this.AddChild();
            _ComponentList = new List<IComponent>();
            foreach (var kvp in this._View)
            {
                if (kvp.Key.Equals("properties"))
                {
                    this.SetPropertyList(kvp.Value as List<Dictionary<string, object>>);
                }
                else
                {
                    this.SetWindowProperty(kvp.Key, kvp.Value);
                }
            }
        }

        protected virtual void SetReceiveData(object data, int actionType) { }


        public void GridPageLoad()
        {
            this.GetElements().ForEach(c => this.Grid.Children.Add(c));

            this.EventLoad();
            this.DataLoadAsync();
        }

        public void DataLoadAsync()
        {
            Task.Run(() =>
            {
                Thread.Sleep(100);
                this.Window.Dispatcher.Invoke(() =>
                {
                    try
                    {
                        this.DataLoad();
                    }
                    catch (Exception ex)
                    {
                        Utility.Common.Alert("BaseWindows", "DataLoad", ex);
                    }
                });
            });
        }

        public void AddChild()
        {
            if (_IsDialog)
            {
                this.Grid.Width = Width;
                this.Grid.Height = Height;
                System.Windows.Controls.Panel.SetZIndex(this.Grid, Utility.Common.GetPanelZIndex());
                System.Windows.Controls.Grid.SetRowSpan(this.Grid, _GridRowCount == 0 ? 1 : _GridRowCount);
                System.Windows.Controls.Grid.SetColumnSpan(this.Grid, _GridColumnCount == 0 ? 1 : _GridColumnCount);
                ParentWindow.Grid.Children.Add(this.Grid);
            }
            else if (this._PagePanel != null)
            {
                this._PagePanel.Children.Cast<System.Windows.FrameworkElement>().ToList().ForEach(f => f.Visibility = System.Windows.Visibility.Collapsed);
                this._PagePanel.Children.Add(this.Grid);
            }
            else
            {
                this.Grid.Width = Width;
                this.Grid.Height = Height;
                MethodInfo m = this.Window.GetType().GetMethod("AddChildControl");
                if (m != null) m.Invoke(this.Window, new object[] { this.Grid });
            }
        }

        public void SetGridVisbile()
        {
            var list = this._PagePanel.Children.Cast<System.Windows.FrameworkElement>().ToList();
            list.ForEach(f =>
            {
                if (this.Grid.Name != f.Name) f.Visibility = System.Windows.Visibility.Collapsed;
            });
            this.Grid.Visibility = System.Windows.Visibility.Visible;

            this.ShowLoad();
        }

        public bool IsNoSetNavMenu { get; set; }

        public Action RefreshAction { get; set; }

        public virtual void ShowLoad()
        {

        }

        public void SetVisible(IWindow preWindow, Dictionary<string,object> paramters)
        {
            _Parameters = paramters;
            if (preWindow != null)
            {
                if (preWindow.ParentWindow.Id == this.ParentWindow.Id || this.ParentWindow.Name == "Index") SetGridVisbile();
                else
                {
                    SetGridVisbile();
                    this.ParentWindow.SetGridVisbile();
                }
            }
        }

        public System.Windows.Controls.Grid GetGrid(Dictionary<string, object> view)
        {
            string gridRows = view.GetStringValue("GridRows");
            string gridColumns = view.GetStringValue("GridColumns");
            string name = view.GetStringValue("name");

            System.Windows.Controls.Grid grid = new System.Windows.Controls.Grid();
            if (!string.IsNullOrEmpty(name)) grid.Name = string.Format("grid_{0}", name);
            else grid.Name = string.Format("grid_{0}", this.Name);

            if (!string.IsNullOrEmpty(gridRows))
            {
                gridRows.Split(new char[] { ',', '，' }).ToList().ForEach(r =>
                {
                    _GridRowCount += 1;
                    if (r == "*") grid.RowDefinitions.Add(new System.Windows.Controls.RowDefinition() { Height = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) });
                    else grid.RowDefinitions.Add(new System.Windows.Controls.RowDefinition() { Height = new System.Windows.GridLength(double.Parse(r)) });
                });
            }

            if (!string.IsNullOrEmpty(gridColumns))
            {
                gridColumns.Split(new char[] { ',', '，' }).ToList().ForEach(r =>
                {
                    _GridColumnCount += 1;
                    if (r == "*") grid.ColumnDefinitions.Add(new System.Windows.Controls.ColumnDefinition() { Width = new System.Windows.GridLength(1, System.Windows.GridUnitType.Star) });
                    else grid.ColumnDefinitions.Add(new System.Windows.Controls.ColumnDefinition() { Width = new System.Windows.GridLength(double.Parse(r)) });
                });
            }

            return grid;
        }

        public System.Windows.Window GetNewWindow()
        {
            System.Windows.Window newWindow = (System.Windows.Window)Activator.CreateInstance(MainWindow.WindowType);
            newWindow.ShowInTaskbar = false;
            return newWindow;
        }

        protected void SetPropertyList(List<Dictionary<string, object>> dictList)
        {
            dictList.ForEach(p =>
            {
               InitComponent(p, _ComponentList);
            });
        }

        public void InitComponent(Dictionary<string, object> dict, List<IComponent> componentList)
        {
            switch (dict.GetStringValue("type"))
            {
                //case "GroupBox": componentList.Add(new GroupBoxComponent(dict, window)); break;
                case "StackPanel":
                case "WrapPanel":
                case "Grid":
                case "Canvas":
                case "DockPanel": componentList.Add(new PanelComponent(dict, this)); break;
                case "Border": componentList.Add(new BorderPanelComponent(dict, this)); break;
                //case "LabelPanel": componentList.Add(new LabelComponent(dict, window)); break;
                case "ScrollViewer": componentList.Add(new ScrollViewerComponent(dict, this)); break;
                //case "GridView": componentList.Add(new GridView(dict, window)); break;
                //case "ImageTextButton": componentList.Add(new ImageTextButtonComponent(dict, window)); break;
                //case "PictureBoxInk": componentList.Add(new PictureBoxInkComponent(dict, window)); break;
                case "StackPanelButton": componentList.Add(new StackPanelButtonComponent(dict, this)); break;
                //case "LeftCenterRightBackImageButton": componentList.Add(new LeftCenterRightBackImageButtonComponent(dict, window)); break;
                case "WebBrowser": componentList.Add(new WebBrowserComponent(dict, this)); break;
                //case "CheckBoxText": componentList.Add(new CheckBoxTextComponent(dict, window)); break;
                //case "RadioText": componentList.Add(new RadioTextComponent(dict, window)); break;
                case "WindowsFormsHost": componentList.Add(new WindowsFormsHostComponent(dict, this)); break;
                case "Popup": componentList.Add(new PopupComponent(dict, this)); break;
                //case "DocumentViewer": componentList.Add(new DocumentViewerComponent(dict, window)); break;
                case "InkCanvas": componentList.Add(new InkCanvasComponent(dict, this)); break;
                //case "Shape": componentList.Add(new ShapeComponent(dict, window)); break;
                //case "ListView": componentList.Add(new ListViewComponent(dict, window)); break;
                //case "DataGridView": componentList.Add(new DataGridView(dict, window)); break;
                //case "TabControl": componentList.Add(new TabControlComponent(dict, window)); break;
                //case "TabItem": componentList.Add(new TabItemComponent(dict, window)); break;
                case "VlcPlayer": componentList.Add(new VlcPlayerComponent(dict, this)); break;
                case "ThemeView": break;
                default: componentList.Add(new PropertyItem(dict, this)); break;
            }
        }


        protected System.Windows.Thickness GetThickness(string value)
        {
            string[] vs = value.Split(',');
            if (vs.Length == 4)
            {
                return new System.Windows.Thickness(double.Parse(vs[0]), double.Parse(vs[1]), double.Parse(vs[2]), double.Parse(vs[3]));
            }

            return new System.Windows.Thickness();
        }

        protected void SetWindowProperty(string name, object value)
        {
            if (this._IsDialog)
            {
                switch (name)
                {
                    case "Width": this.Grid.Width = Convert.ToDouble(value); break;
                    case "Height": this.Grid.Height = Convert.ToDouble(value); break;
                    case "Margin": this.Grid.Margin = GetThickness((string)value); break;
                    case "VerticalAlignment": this.Grid.VerticalAlignment = Utility.Common.GetVerticalAlignment((string)value); break;
                    case "HorizontalAlignment": this.Grid.HorizontalAlignment = Utility.Common.GetHorizontalAlignment((string)value); break;
                }
            }
            else if (this._PagePanel != null)
            {
            }
            else
            {
                switch (name)
                {
                    case "Title": Window.Title = (string)value; break;
                    case "Width": Window.Width = Convert.ToDouble(value); break;
                    case "Height": Window.Height = Convert.ToDouble(value); break;
                    case "WindowStyle": SetWindowStyle((string)value); break;
                    case "StartPosition": SetWindowStartupLocation((string)value); break;
                    case "WindowState": SetFormWindowState((string)value); break;
                    case "BackImageUrl": SetBackgroundImage((string)value); break;
                    case "ResizeMode": SetResizeMode((string)value); break;
                    case "BackColor": Window.Background = Utility.Common.GetColorBrush((string)value, _Opacity); Window.AllowsTransparency = true; break;
                }
            }
        }

        protected void SetBackgroundImage(string url)
        {
            string stretch = _View.GetStringValue("BackImageStretch");
            stretch = string.IsNullOrEmpty(stretch) ? "UniformToFill" : stretch;

            var img = Utility.Common.GetImageSource(url);
            if (img == null) return;
            System.Windows.Media.ImageBrush imgBrush = new System.Windows.Media.ImageBrush();
            imgBrush.ImageSource = img;
            imgBrush.Stretch = Common.GetStretch(stretch);
            this.Window.Background = imgBrush;
        }

        protected void SetBackgroundImage(System.Windows.Window win, string url, string stretch)
        {
            stretch = string.IsNullOrEmpty(stretch) ? "UniformToFill" : stretch;

            var img = Utility.Common.GetImageSource(url);
            if (img == null) return;
            System.Windows.Media.ImageBrush imgBrush = new System.Windows.Media.ImageBrush();
            imgBrush.ImageSource = img;
            imgBrush.Stretch = Common.GetStretch(stretch);
            win.Background = imgBrush;
        }

        public void SetGridBackgroundImage(System.Windows.Controls.Grid grid, System.Windows.Media.ImageSource imageSource, string stretch)
        {
            if (imageSource != null)
            {
                stretch = string.IsNullOrEmpty(stretch) ? "UniformToFill" : stretch;
                System.Windows.Media.ImageBrush img = new System.Windows.Media.ImageBrush();
                img.ImageSource = imageSource;
                img.Stretch = Common.GetStretch(stretch);
                grid.Background = img;
            }
            //else grid.Background = Common.GetColor(color);
        }


        protected void SetGridBackColor(string color)
        {
            this.Grid.Background = Utility.Common.GetColorBrush(color, _Opacity);
        }

        protected void SetFormWindowState(string value)
        {
            switch (value)
            {
                case "Maximized": Window.WindowState = System.Windows.WindowState.Maximized; break;
                case "Minimized": Window.WindowState = System.Windows.WindowState.Minimized; break;
                case "Normal": Window.WindowState = System.Windows.WindowState.Normal; break;
            }
        }

        void SetResizeMode(string value)
        {
            switch (value)
            {
                case "CanMinimize": Window.ResizeMode = System.Windows.ResizeMode.CanMinimize; break;
                case "CanResize": Window.ResizeMode = System.Windows.ResizeMode.CanResize; break;
                case "CanResizeWithGrip": Window.ResizeMode = System.Windows.ResizeMode.CanResizeWithGrip; break;
                case "NoResize": Window.ResizeMode = System.Windows.ResizeMode.NoResize; break;
            }
        }

        private void SetWindowStartupLocation(string value)
        {
            switch (value)
            {
                case "CenterScreen": Window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen; break;
                case "CenterOwner": Window.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterOwner; if (ParentWindow != null && ParentWindow.Window.Visibility == System.Windows.Visibility.Visible) Window.Owner = ParentWindow.Window; break;
                case "Manual": Window.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual; break;
            }
        }

        private void SetWindowStyle(string value)
        {
            switch (value)
            {
                case "SingleBorderWindow": Window.WindowStyle = System.Windows.WindowStyle.SingleBorderWindow; break;
                case "ThreeDBorderWindow": Window.WindowStyle = System.Windows.WindowStyle.ThreeDBorderWindow; break;
                case "ToolWindow": Window.WindowStyle = System.Windows.WindowStyle.ToolWindow; break;
                case "None": Window.WindowStyle = System.Windows.WindowStyle.None; Window.ResizeMode = System.Windows.ResizeMode.NoResize; break;
            }
        }

        /// <summary>
        /// 获取控件元素列表
        /// </summary>
        /// <returns></returns>
        public virtual List<System.Windows.FrameworkElement> GetElements()
        {
            List<System.Windows.FrameworkElement> controlList = new List<System.Windows.FrameworkElement>();

            if (this._ComponentList.Count > 0)
            {
                controlList.AddRange((from a in this._ComponentList
                                      from b in a.GetElements()
                                      select b));
            }

            _WindowControlList = controlList;

            return controlList;
        }

        /// <summary>
        /// 事件加载
        /// </summary>
        public virtual void EventLoad()
        {
            if (this._ComponentList.Count > 0) this._ComponentList.ForEach(c => c.EventLoad());
        }

        /// <summary>
        /// 数据加载
        /// </summary>
        public virtual void DataLoad()
        {
            if (this._ComponentList.Count > 0) this._ComponentList.ForEach(c => c.DataLoad());
        }

        /// <summary>
        /// 事件调用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="control"></param>
        public virtual void EventInvoke(object sender, EventArgs e, IControl control)
        {
            var eventAction = control.Property.GetValue<Dictionary<string, object>>("EventAction");
            if (eventAction != null)
            {
                string className = eventAction.GetStringValue("className");
                string mehtodName = eventAction.GetStringValue("methodName");

                var p = EventAction.GetType().GetProperty(className);
                if (p != null)
                {
                    var m = p.PropertyType.GetMethod(mehtodName);
                    if (m != null) m.Invoke(p.GetValue(EventAction), new object[] { this, control, eventAction });
                }
            }
            else
            {
                string eventActionName = control.Property.GetStringValue("EventActionName");
                if (!string.IsNullOrEmpty(eventActionName))
                {
                    var m = this.GetType().GetMethod(eventActionName);
                    if (m != null) m.Invoke(this, new object[] { control });
                }
            }
        }

        /// <summary>
        /// 双击或多击事件调用
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        /// <param name="control"></param>
        public virtual void DoubleEventInvoke(object sender, EventArgs e, IControl control)
        {
        }

        public Dictionary<string, object> GetEditData(out string message)
        {
            message = string.Empty;
            Dictionary<string, object> dict = new Dictionary<string, object>();

            foreach (IComponent c in this._ComponentList)
            {
                if (c.IsEdit())
                {
                    if (!c.ValidateNullable(out message)) break;
                    dict.Add(c.Name, c.GetValue());
                }
            }

            return dict;
        }

        protected IComponent GetComponent(string name)
        {
            return this.ComponentList.Where(w => w.Name.Equals(name)).FirstOrDefault();
        }

        protected IComponent GetComponent(IComponent component, string name)
        {
            return component ?? this.ComponentList.Where(w => w.Name.Equals(name)).FirstOrDefault();
        }

        protected System.Windows.FrameworkElement GetWindowControl(string name)
        {
            return this._WindowControlList.Where(w => w.Name.Equals(name)).FirstOrDefault();
        }

        protected void SetControlValue(string name, object value)
        {
            IControl ctl = this.ControlList.Where(w => w.Name == name).FirstOrDefault();
            if (ctl != null) ctl.SetValue(value);
        }

        protected IControl GetControl(IControl ctl, string name, bool blFullName = false)
        {
            if (blFullName) return ctl ?? ControlList.Where(w => w.FullName == name).FirstOrDefault();
            else return ctl ?? ControlList.Where(w => w.Name == name).FirstOrDefault();
        }

        protected IControl GetControl(string name)
        {
            return ControlList.Where(w => w.Name == name).FirstOrDefault();
        }

        protected bool _IsDialogBack { get; set; }

        private void ShowAlertConfrim(string message, bool blConfrim, Action callback)
        {
            Window.Dispatcher.Invoke(() =>
            {
                try
                {
                    IWindow parentWindow = this.IsDialogWindow ? this.ParentWindow : this;
                    MainWindow mainWindow = new MainWindow(this.GetNewWindow(), "AlertConfrim", parentWindow, false, false);
                    AlertConfrim alertConfrim = (AlertConfrim)mainWindow.CurrentWindow;

                    if (blConfrim) alertConfrim.Confrim(message, _IsDialogBack);
                    else alertConfrim.Alert(message, _IsDialogBack);

                    mainWindow.ShowDialog(callback);
                }
                catch (Exception ex)
                {
                    Utility.LoggerProxy.Exception(Name, "ShowAlertConfrim", ex);
                    Utility.Common.Alert(message);
                }
            });
        }

        public List<IControl> PopupList { get; set; }

        public void ShowAlertMessageList(string message, List<Dictionary<string, object>> messageList, Action callback = null)
        {
            //Window.Dispatcher.Invoke(() =>
            //{
            //    try
            //    {
            //        IWindow parentWindow = this.IsDialogWindow ? this.ParentWindow : this;
            //        MainWindow mainWindow = new MainWindow(id, this.GetNewWindow(), "AlertMessageList", parentWindow, false);

            //        AlertMessageList alertMessageList = (AlertMessageList)mainWindow.CurrentWindow;
            //        alertMessageList.Alert(message, messageList);

            //        mainWindow.ShowDialog(callback);
            //    }
            //    catch (Exception ex)
            //    {
            //        Utility.LoggerProxy.Exception(Name, "ShowAlertConfrim", ex);
            //        Utils.Common.Alert(message);
            //    }
            //});
        }

        public void Alert(string message, Action callback = null)
        {
            ShowAlertConfrim(message, false, callback);
        }

        public void Confrim(string message, Action callback)
        {
            ShowAlertConfrim(message, true, callback);
        }

        /// <summary>
        /// 弹出对话框
        /// </summary>
        /// <param name="message"></param>
        /// <returns></returns>
        public void Alert(string entityName, string methodName, Exception ex, Action callback = null)
        {
            ex = Utility.Common.GetInnerException(ex);
            Utility.LoggerProxy.Exception(entityName, methodName, ex);
            Alert(ex.Message, callback);
        }

        public void Alert(string entityName, string methodName, string message, Exception ex, Action callback = null)
        {
            ex = Utility.Common.GetInnerException(ex);
            Utility.LoggerProxy.Exception(entityName, methodName, ex);

            StringBuilder sb = new StringBuilder();
            sb.AppendLine(ex.Message);
            sb.AppendLine(message);
            Alert(sb.ToString(), callback);
        }

        protected Dictionary<string, object> _Parameters { get; set; }

        /// <summary>
        /// 是否关闭
        /// </summary>
        public bool IsClosed { get; set; }

        /// <summary>
        /// 是否弹出窗体方式
        /// </summary>
        public bool IsDialogWindow { get; set; }

        public bool IsShowWindow { get; set; }

        /// <summary>
        /// 关闭窗体
        /// </summary>
        /// <returns></returns>
        public virtual void CloseWindow()
        {
            IsClosed = true;
        }

        public double ShowGridColumn(double width, int index, bool blVisible)
        {
            if (blVisible)
            {
                if (width == 0)
                {
                    string gridColumns = _View.GetStringValue("GridColumns");
                    string[] vs = gridColumns.Split(new char[] { ',', '，' });
                    width = double.Parse(vs[index]);
                }
                this.Grid.ColumnDefinitions[index].Width = new System.Windows.GridLength(width);
            }
            else
            {
                if (width == 0) width = this.Grid.ColumnDefinitions[index].Width.Value;
                this.Grid.ColumnDefinitions[index].Width = new System.Windows.GridLength(0);
            }

            return width;
        }

        public double ShowGridRow(double height, int index, bool blVisible)
        {
            if (blVisible)
            {
                if (height == 0)
                {
                    string gridColumns = _View.GetStringValue("GridRows");
                    string[] vs = gridColumns.Split(new char[] { ',', '，' });
                    height = double.Parse(vs[index]);
                }
                this.Grid.RowDefinitions[index].Height = new System.Windows.GridLength(height);
            }
            else
            {
                if (height == 0) height = this.Grid.RowDefinitions[index].Height.Value;
                this.Grid.RowDefinitions[index].Height = new System.Windows.GridLength(0);
            }

            return height;
        }

        public virtual void PageLoad() { }

        double _TopPanelLength { get; set; }

        protected void SetTopPanelVisible(bool blVisible, int index)
        {
            _TopPanelLength = ShowGridRow(_TopPanelLength, index, blVisible);
        }

        double _BottomPanelLength { get; set; }

        protected void SetBottomPanelVisible(bool blVisible, int index)
        {
            _BottomPanelLength = ShowGridRow(_BottomPanelLength, index, blVisible);
        }

        public void CloseDialog()
        {
            if (IsDialogWindow && !IsShowWindow) this.Window.DialogResult = false;
            else if (IsShowWindow && this.Window.IsActive) this.Window.Close();
        }

        public Task TaskRun(string name, bool blAlert, Action action)
        {
            return Task.Run(() =>
            {
                try
                {
                    action();
                }
                catch (Exception ex)
                {
                    if (blAlert) Alert(Name, name, ex);
                    else Utility.LoggerProxy.Exception(Name, name, ex);
                }
            });
        }

        protected virtual void SetClosePage(object data, Action closeAction = null)
        {
            Title = _View.GetStringValue("Title");

            foreach (System.Windows.UIElement g in this.Grid.Children)
            {
                if (g.Visibility != System.Windows.Visibility.Collapsed) g.Visibility = System.Windows.Visibility.Collapsed;
            }
            FirstGrid.Element.Visibility = System.Windows.Visibility.Visible;
        }

        protected int ClosePageActionType { get; set; }
        protected IControl FirstGrid { get; set; }

        public void ClosePage()
        {
        }

        protected void SetChildWindow(IWindow win, Func<IWindow> initWindow)
        {
            foreach (System.Windows.FrameworkElement g in this.Grid.Children)
            {
                if (g.Visibility != System.Windows.Visibility.Collapsed) g.Visibility = System.Windows.Visibility.Collapsed;
            }

            bool blFirst = win == null;
            if (!blFirst) win.Grid.Visibility = System.Windows.Visibility.Visible;
            else
            {
                win = initWindow();
                win.GetElements().ForEach(c => win.Grid.Children.Add(c));
            }

            Title = win.Title;

            if (blFirst)
            {
                win.EventLoad();
                win.DataLoadAsync();
            }
        }
    }
}
